package com.tianhao.luo.sync;

/**
 * 使用wait和notifyAll进行线程间通信
 * 控制间歇打印1和0
 *
 * @author tianhao.luo@hand-china.com
 */
public class ThreadNotifyDemo {

    public static void main(String[] args) {
        Share share = new Share();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"aa").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"bb").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"cc").start();



        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"dd").start();
    }


    static class Share {
        /**
         * 初始值
         */
        private int number = 0;


        public synchronized void incr() throws InterruptedException {
            // 使用if进行判断时，可能出现虚假唤醒，即这个if判断刚执行完毕就被唤醒了，导致number进行了++
            while (number != 0) {
                // number不为0，进行等待
                this.wait();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + ":: " + number);
            // 通知其他线程
            this.notifyAll();
        }

        public synchronized void decr() throws InterruptedException {
            while (number != 1) {
                // number为0，进行等待
                this.wait();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + ":: " + number);
            // 通知其他线程
            this.notifyAll();
        }
    }
}
